﻿using System;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml;
using System.Data;
using NHibernate.Expression;
using Schooll.Model;

/// <summary>
/// Descripción breve de XmlDataAlumnos
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class XmlDataAlumnos : System.Web.Services.WebService
{
    private const string sGuardarEn = "d:\\temp\\miData.xml";

    private Planilla Pla = new Planilla();

    XmlDocument dom = new XmlDocument();

    [WebMethod]
    public XmlDocument getDataNota(int idCurso, int idMateria, Periodos Per)
    {
        return getDataNota(idCurso, idMateria, Per, false);
    }
    [WebMethod]
    public XmlDocument getDataNota(int idCurso, int idMateria, Periodos Per, bool ShowCuatrimestral)
    {

        Pla.IdMateria = idMateria;
        Pla.Per = Per;
        Pla.IdCurso = idCurso;

        //ds.Tables.Add("Alunos").Rows.Add("Alumno");
        DataTable dt = AlumnosCurso.Tabla("Proc_getAlumnosFromCurso " + idCurso.ToString() + "," + Per.Anio.ToString());

        //armar el listado de alumnos
        XmlElement alumnos = dom.CreateElement("alumnos");
        dom.AppendChild(alumnos);

        foreach (DataRow r in dt.Rows)
        {
            XmlElement node = dom.CreateElement("alumno");
            node.SetAttribute("nombre", r["alumno"].ToString());
            node.SetAttribute("idAlumnoCurso", r["idAlumnoCurso"].ToString());
            node.SetAttribute("idNota", Pla.IdNota.ToString());
            Pla.IdAlumnoCurso = int.Parse(r["idAlumnoCurso"].ToString());


            //Agrego las cuatrimestrales
            addCuatrimestrales(node, Pla);


            //agrego los periodos con las notas correspondientes
            addPeriodos(node, Pla);

            //Obtengo todos lo periodo descartando las cuatrimestrales
            string sSql = @"select idPeriodo from periodos p where nroperiodo=" + Pla.Per.NroPeriodo.ToString() + " and idsede = " + Pla.Per.IdSede.ToString() + " and idtipoPlanilla = " + Pla.Per.idTipoPlanilla.ToString();
            if (!ShowCuatrimestral) sSql += " and not exists(select 1 from periodocategoria where idperiodo = p.idperiodo)";
            DataTable dt2 = Periodos.Tabla(sSql);

            for (int x = 0; x < dt2.Rows.Count; x++)
            {
                string actual = "";
                Pla.Per = Periodos.Buscar("Idperiodo =" + dt2.Rows[x]["idPeriodo"].ToString());
                if (Per.IdPeriodo == Pla.Per.IdPeriodo)
                {
                    actual = "true";
                }
                //agregar las notas y las cuatrimestrales cuatrimestrales
                addNotas(node, Pla, actual);


                alumnos.AppendChild(node);
            }


        }

        addSignificadoNotas(alumnos);
        if (sGuardarEn.Length > 0) dom.Save(sGuardarEn);
        return dom;
    }

    void addSignificadoNotas(XmlElement node)
    {
        string Sql = "proc_NotasSignificado " + biFactory.Materia().IdIdioma;
        DataTable dt = AlumnosCurso.Tabla(Sql);
        XmlElement elemento = dom.CreateElement("notas");
        XmlElement node1;
        foreach (DataRow r in dt.Rows)
        {
            node1 = dom.CreateElement("nota");
            node1.SetAttribute("letra", r["Letra"].ToString());
            node1.SetAttribute("valor", r["Numero"].ToString());
            node1.SetAttribute("descripcion", r["detalle"].ToString());
            elemento.AppendChild(node1);
        }
        node.AppendChild(elemento);

    }

    private void addPeriodos(XmlElement node, Planilla pla)
    {
        string Sql = "select distinct anio, Descripcion, NroPeriodo from periodos where idsede = " + pla.Per.IdSede + " and idTipoPlanilla = " + pla.Per.idTipoPlanilla.ToString();
        DataTable dt = AlumnosCurso.Tabla(Sql);
        XmlElement Periodos = dom.CreateElement("periodos");
        XmlElement node1;
        foreach (DataRow r in dt.Rows)
        {
            node1 = dom.CreateElement("periodo");
            node1.SetAttribute("name", r["Descripcion"].ToString());
            if (int.Parse(r["NroPeriodo"].ToString()) == pla.Per.NroPeriodo) node1.SetAttribute("actual", "true");
            //valor de la nota
            string sProm = "";

            node1.InnerText = GetNotaPromedioPeriodo(pla, r["NroPeriodo"].ToString(), out sProm);
            if (pla.Per.idTipoPlanilla == 1)
            {
                //si la planilla es la 1 se muestran letras
                string ssql = "select Numero from dbo.TipoNotas where numero like '" + node1.InnerText + "%' and idioma = " + +SchoolsBI.Materia.Buscar("IdMateria =" + pla.IdMateria).IdIdioma;

                DataTable dtsa = SchoolsBI.TipoNotas.Tabla(ssql);

                if (dtsa.Rows.Count > 0)
                    node1.InnerText = dtsa.Rows[0][0].ToString();
                else
                    node1.InnerText = "";
            }
            node1.SetAttribute("Promedio", sProm.Substring(0, sProm.IndexOf(".") + 3));
            node1.SetAttribute("IdMateria", pla.IdMateria.ToString());
            node1.SetAttribute("NroPeriodo", r["NroPeriodo"].ToString());
            node1.SetAttribute("IdSede", pla.Per.IdSede.ToString());
            Periodos.AppendChild(node1);
        }

        node.AppendChild(Periodos);
    }
    private void addCuatrimestrales(XmlElement node, Planilla pla)
    {


        string Sql = "proc_getCuatrimestral " + pla.IdMateria.ToString() + "," + pla.IdAlumnoCurso.ToString();
        DataTable dt = AlumnosCurso.Tabla(Sql);

        XmlElement Periodos = dom.CreateElement("Cuatrimestrales");
        XmlElement node1;
        foreach (DataRow r in dt.Rows)
        {
            node1 = dom.CreateElement("cuatrimetral");
            node1.SetAttribute("name", r["Descripcion"].ToString());
            //valor de la nota


            node1.InnerText = r["NOta"].ToString();
            if (pla.Per.idTipoPlanilla == 1)
            {
                //si la planilla es la 1 se muestran letras
                string ssql = "select Numero from dbo.TipoNotas where numero like '" + node1.InnerText + "%' and idioma = " + +SchoolsBI.Materia.Buscar("IdMateria =" + pla.IdMateria).IdIdioma;

                DataTable dtsa = SchoolsBI.TipoNotas.Tabla(ssql);

                if (dtsa.Rows.Count > 0)
                    node1.InnerText = dtsa.Rows[0][0].ToString();
                else
                    node1.InnerText = "";
            }
            //si la nota es un cero se muestra como ausente
            if (node1.InnerText == "0.00")
            {
                node1.InnerText = "A";
            }
            node1.SetAttribute("IdMateria", pla.IdMateria.ToString());
            node1.SetAttribute("NroPeriodo", r["NroPeriodo"].ToString());
            node1.SetAttribute("IdSede", pla.Per.IdSede.ToString());

            Periodos.AppendChild(node1);
        }
        node.AppendChild(Periodos);
    }
    private string GetNotaPromedioPeriodo(Planilla pla, string p, out string Promedio)
    {
        DataTable dt = AlumnosCurso.Tabla("Proc_PromedioPeriodo " + p + "," + pla.Per.IdSede + " , " + pla.IdAlumnoCurso + "," + pla.IdMateria.ToString());

        if (dt.Rows.Count > 0)
        {
            Promedio = dt.Rows[0]["Promedio"].ToString();
            string valor = Redondear(Single.Parse(dt.Rows[0]["Promedio"].ToString()), pla.Per.idTipoPlanilla);
            if (Single.Parse(valor) > 0)
            {
                return FormatearDecimales(valor);
            }
            else
            {
                return "sn";
            }

        }
        else
        {
            Promedio = "sn";
            return "sn";
        }

    }
    private string GetNotaPromedioPeriodo(string NroPeriodo, string idSede, string IdAlumnoCurso, string IdMateria, out string Promedio)
    {

        SchoolsBI.Materia oMat = SchoolsBI.Materia.Buscar("idMateria = " + IdMateria);

        DataTable dt = AlumnosCurso.Tabla("Proc_PromedioPeriodo " + NroPeriodo + "," + idSede + " , " + IdAlumnoCurso + "," + IdMateria);
        if (dt.Rows.Count > 0)
        {
            Promedio = dt.Rows[0]["Promedio"].ToString();
            string valor = Redondear(Single.Parse(dt.Rows[0]["Promedio"].ToString()), oMat.idTipoPlanilla);
            if (Single.Parse(valor) > 0)
            {
                return FormatearDecimales(valor);
            }
            else
            {
                return "sn";
            }

        }
        else
        {
            Promedio = "sn";
            return "sn";
        }

    }
    private void addNotas(XmlElement node, Planilla pla, string actual)
    {
        //selecciona las modalidades por materia
        DataTable dt = AlumnosCurso.Tabla("select idMateriaModalidad, Modalidad from materiaModalidad  where idmateria = " + pla.IdMateria.ToString());
        XmlElement Elemento = dom.CreateElement("notas");

        Elemento.SetAttribute("NroPeriodo", pla.Per.NroPeriodo.ToString());
        Elemento.SetAttribute("IdPeriodo", pla.Per.IdPeriodo.ToString());
        Elemento.SetAttribute("Periodo", pla.Per.Descripcion.ToString());
        Elemento.SetAttribute("Particion", pla.Per.Particion.ToString());
        if (actual.Length > 0) Elemento.SetAttribute("actual", actual);
        XmlElement node1;
        foreach (DataRow r in dt.Rows)
        {
            node1 = dom.CreateElement("nota");
            node1.SetAttribute("name", r["Modalidad"].ToString());
            node1.SetAttribute("IdModalidad", r["idMateriaModalidad"].ToString());
            pla.IdModalidad = Int32.Parse(r["idMateriaModalidad"].ToString());

            addNotasModalidad(node1, pla, r["idMateriaModalidad"].ToString());
            Elemento.AppendChild(node1);
        }

        //add nota auxiliar
        node1 = dom.CreateElement("nota");
        node1.SetAttribute("name", "Auxiliar");
        node1.SetAttribute("IdModalidad", "0");
        addNotasModalidad(node1, pla, "0");
        Elemento.AppendChild(node1);


        node.AppendChild(Elemento);


    }
    private void addNotasModalidad(XmlElement node, Planilla pla, string idModalidad)
    {
        //obtengo las notas para el alumno
        string sSql;
        sSql = @"select nm.* from notas n inner join notasmodalidad nm on n.idNota = nm.Idnota where idMateria = " + pla.IdMateria + " and idAlumnoCurso = " + pla.IdAlumnoCurso + "  and idPeriodo =  " + pla.Per.IdPeriodo + " and IdModalidad =" + idModalidad + " order by nroNota";

        DataTable dt = Alumnos.Tabla(sSql);

        XmlElement Elemento = dom.CreateElement("item");
        XmlElement node1;
        //cuantas notas necesito?
        int nCantNotas = 2;
        int iNotapos = 0;

        foreach (DataRow r in dt.Rows)
        {

            while ((iNotapos + 1) < int.Parse(r["NroNota"].ToString()))
            {
                node1 = dom.CreateElement("item");
                node1.SetAttribute("detalle", r["Observacion"].ToString());
                node1.SetAttribute("IdModalidad", r["IdModalidad"].ToString());
                node1.SetAttribute("IdNota", "");
                node1.SetAttribute("IdNotaModalidad", "");
                node1.SetAttribute("NroNota", (iNotapos + 1).ToString());
                node1.InnerText = "sn";
                node.AppendChild(node1);
                iNotapos += 1;
            }

            node1 = dom.CreateElement("item");
            node1.SetAttribute("detalle", r["Observacion"].ToString());
            node1.SetAttribute("IdModalidad", r["IdModalidad"].ToString());
            node1.SetAttribute("IdNota", r["IdNota"].ToString());
            node1.SetAttribute("IdNotaModalidad", r["IdNotaModalidad"].ToString());
            node1.SetAttribute("NroNota", r["NroNota"].ToString());
            node1.InnerText = r["Nota"].ToString().Replace(',', '.');
            node.AppendChild(node1);
            iNotapos += 1;
        }

        for (int p = iNotapos; p < nCantNotas; p++)
        {
            node1 = dom.CreateElement("item");
            node1.SetAttribute("detalle", "--");
            node1.SetAttribute("IdModalidad", "");
            node1.SetAttribute("IdNota", "");
            node1.SetAttribute("IdNotaModalidad", "");
            node1.InnerText = "sn";
            node.AppendChild(node1);
        }



    }

    //crear la planila para el curso
    string GetNota(Planilla pla, int IdPeriodo)// string idAlumnoCurso, string  IdMateria, Periodos Per) 
    {
        string Sql = @"select idNota, Nota from notas where idAlumnoCurso = " + pla.IdAlumnoCurso.ToString() + " and idMateria = " + pla.IdMateria.ToString() + " and idPeriodo = " + IdPeriodo.ToString();
        DataTable dt = AlumnosCurso.Tabla(Sql);
        if (dt.Rows.Count > 0)
        {
            pla.IdNota = Convert.ToInt32(dt.Rows[0]["IdNota"]);
            return dt.Rows[0]["Nota"].ToString().Replace(',', '.');
        }
        else
        {
            pla.IdNota = 0;
            return "SN";
        }



    }
    public string Redondear(Single valor, Planilla pla)
    {
        if (pla.Per.idTipoPlanilla == 1)
        {
            return RedondearPrimaria(valor);

        }
        else
        {
            return (System.Math.Round(valor, MidpointRounding.ToEven)).ToString();
        }

    }

    #region "Redondeos"
    public string Redondear(Single valor, int IdTipoPlanilla)
    {
        if (IdTipoPlanilla == 1)
        {
            return RedondearPrimaria(valor);

        }
        else
        {
            return RedondearSecundaria(valor);
        }

    }
    public string RedondearSecundaria(Single nvalor)
    {
        int Entero = (int)nvalor;
        float dec = (nvalor - (int)nvalor);
        if (dec >= 0 && dec <= 0.5)
            dec = 0;
        if (dec > 0.5 && dec <= 1)
        {
            dec = 0;
            Entero += 1;
        }
        nvalor = Entero + dec;
        return nvalor.ToString();

    }
    public string RedondearPrimaria(Single nvalor)
    {

        int Entero = (int)nvalor;
        float dec = (nvalor - (int)nvalor);
        if (Entero >= 6 && Entero < 10)
        {
            if (dec >= 0 && dec <= 0.25)
                dec = 0;
            if (dec >= 0.26 && dec <= 0.75)
                dec = 0.5F;
            if (dec > 0.75)
            {
                dec = 0;
                Entero += 1;
            }
        }
        else
        {
            if (dec > 0 && dec <= 0.5)
                dec = 0F;
            if (dec > 0.5)
            {
                dec = 0;
                Entero += 1;
            }

        }
        nvalor = Entero + dec;

        return nvalor.ToString();


    }
    #endregion

    #region "Boletin notas conceptual
    [WebMethod]
    public DataTable getConceptual(int idCurso, int idReunion)
    {
        //obtengo los alumnos
        string sSql = "proc_getAlumnosfromCurso " + idCurso;
        DataTable dtAlumnos = Colegio.Tabla(sSql);

        //obtengo las materias
        sSql = "proc_getMateriasFromIdCurso " + idCurso;
        DataTable dtMaterias = Colegio.Tabla(sSql);
        //obtengo las notas de los conceptos
        sSql = "proc_ConceptoNotas " + idCurso + ", " + idReunion;
        DataTable dtNotas = Colegio.Tabla(sSql);

        DataTable dtConcepto = new DataTable("Concepto");

        DataColumn c;

        c = new DataColumn("ID");
        c.DataType = System.Type.GetType("System.Int32");
        c.Unique = true;

        dtConcepto.Columns.Add(c);

        c = new DataColumn("Alumno");
        c.DataType = System.Type.GetType("System.String");
        c.MaxLength = 60;
        dtConcepto.Columns.Add(c);

        c = new DataColumn("Advertencias Escritas");
        c.DataType = System.Type.GetType("System.String");
        c.MaxLength = 60;
        dtConcepto.Columns.Add(c);

        c = new DataColumn("Tarjetas Amarillas");
        c.DataType = System.Type.GetType("System.String");
        c.MaxLength = 60;
        dtConcepto.Columns.Add(c);

        c = new DataColumn("Inasistencias");
        c.DataType = System.Type.GetType("System.String");
        c.MaxLength = 60;
        dtConcepto.Columns.Add(c);

        //agrego todas las columnas de las materias
        foreach (DataRow rm in dtMaterias.Rows)
        {
            c = new DataColumn(rm["MateriaBoletin"].ToString() + "1");
            c.DataType = System.Type.GetType("System.String");
            c.MaxLength = 60;
            dtConcepto.Columns.Add(c);
            c = new DataColumn(rm["MateriaBoletin"].ToString() + "2");
            c.DataType = System.Type.GetType("System.String");
            c.MaxLength = 60;
            dtConcepto.Columns.Add(c);
        }

        c = new DataColumn("Rendimiento");
        c.DataType = System.Type.GetType("System.String");
        c.MaxLength = 60;
        dtConcepto.Columns.Add(c);

        c = new DataColumn("Actitud");
        c.DataType = System.Type.GetType("System.String");
        c.Caption = "Actitudes";
        c.MaxLength = 60;
        dtConcepto.Columns.Add(c);

        //carga las filas
        foreach (DataRow ra in dtAlumnos.Rows)
        {
            DataRow r = dtConcepto.NewRow();
            r["ID"] = ra["idAlumnoCurso"];
            r["Alumno"] = ra["alumno"];
            //agregar las notas por materia
            //promedio
            PromedioConcepto prdRend = new PromedioConcepto();
            PromedioConcepto prdActi = new PromedioConcepto();

            foreach (DataRow rm in dtMaterias.Rows)
            {
                DataRow[] rNota = dtNotas.Select("IdAlumnoCurso = " + r["ID"].ToString() + " and idmateria = " + rm["IdMateria"].ToString());
                if (rNota.Length > 0)
                {
                    if (rNota[0]["Rendimiento"].ToString() != "-1" && rNota[0]["Rendimiento"].ToString() != "-1.00")
                    {
                        //r[rm["MateriaBoletin"].ToString() + 1] = (dtNotaSig.Select("Numero = " + rNota[0]["Rendimiento"]))[0]["Letra"];
                        r[rm["MateriaBoletin"].ToString() + 1] = rNota[0]["Rendimiento"];
                        prdRend.add(Convert.ToDouble(rNota[0]["Rendimiento"].ToString()));

                    }
                    if (rNota[0]["Actitud"].ToString() != "-1" && rNota[0]["Actitud"].ToString() != "-1.00")
                        //r[rm["MateriaBoletin"].ToString()+2]=(dtNotaSig.Select("Numero = " + rNota[0]["Actitud"]))[0]["Letra"];
                        r[rm["MateriaBoletin"].ToString() + 2] = rNota[0]["Actitud"];
                    prdActi.add(Convert.ToDouble(rNota[0]["Actitud"].ToString()));
                }
            }
            //despues de las materias agrego los promedios calculados
            r["Rendimiento"] = prdRend.promedio;
            r["Actitud"] = prdActi.promedio;
            dtConcepto.Rows.Add(r);
        }
        dtConcepto.WriteXml(sGuardarEn);
        return dtConcepto;

    }
    #endregion

    #region "boletin"

    [WebMethod]
    public XmlDocument getBoletin(int idAlumno)
    {
        //Tipo de materia, para saber como tengo que mostrar las notas y como tengo 
        // que redondear la nota
        Int16 idTipoPlanilla = 0;

        //armar el listado de alumnos
        XmlElement alumno = dom.CreateElement("alumno");
        dom.AppendChild(alumno);

        Alumnos al = Alumnos.Buscar("IdAlumno = " + idAlumno);
        alumno.SetAttribute("nombre", al.Apellido + "," + al.Nombre);


        //obtengo las materias del boletin
        string sql = @"getMateriasBoletin " + idAlumno;

        //obtiene las materias del boletin
        DataTable dtm = Alumnos.Tabla(sql);
        alumno.SetAttribute("Curso", dtm.Rows[0]["Curso"].ToString());
        alumno.SetAttribute("Anio", dtm.Rows[0]["Anio"].ToString());
        alumno.SetAttribute("Turno", dtm.Rows[0]["turno"].ToString());
        alumno.SetAttribute("IdAlumnoCurso", dtm.Rows[0]["IdAlumnoCurso"].ToString());
        alumno.SetAttribute("idSede", dtm.Rows[0]["idSede"].ToString());
        alumno.SetAttribute("idTipoPlanilla", dtm.Rows[0]["idTipoPlanilla"].ToString());
        idTipoPlanilla = Int16.Parse(dtm.Rows[0]["idTipoPlanilla"].ToString());
        //obtene el curso 
        Schooll.Model.CursoAprobacion c = Schooll.Model.CursoAprobacion.FindFirst(Expression.Eq("IdCurso", int.Parse(dtm.Rows[0]["idCurso"].ToString())));

        //agregar las materias
        XmlElement Materias = dom.CreateElement("Materias");
        foreach (DataRow r in dtm.Rows)
        {
            XmlElement Materia = dom.CreateElement("Materia");
            Materia.SetAttribute("IdMateria", r["IdMateria"].ToString());
            Materia.SetAttribute("Nombre", r["Materia"].ToString());
            Materia.SetAttribute("Tipo", r["TipoMateria"].ToString());
            Materias.AppendChild(Materia);
        }
        alumno.AppendChild(Materias);

        //agregar periodos
        sql = @"select p.*, isnull( pc.idtipo,0) idtipo from periodos p left join periodocategoria pc on p.IdPeriodo = pc.IdPeriodo 
                where idTipoPlanilla = " + alumno.GetAttribute("idTipoPlanilla") + @"
                and idsede = " + alumno.GetAttribute("idSede") +
                " order by fechadesde, nroperiodo, ordenperiodo";
        DataTable dt = Alumnos.Tabla(sql);

        XmlElement Periodos = dom.CreateElement("Periodos");
        String sPeriodoactual = "";

        //Recorre los periodos y los va calculando
        XmlElement PeriodoPar = null;
        foreach (DataRow r in dt.Rows)
        {
            XmlElement Periodo = dom.CreateElement("Periodo");

            if (sPeriodoactual == "")
            {
                sPeriodoactual = r["nroPeriodo"].ToString();
                PeriodoPar = dom.CreateElement("Periodo");
            }

            if (sPeriodoactual != r["nroPeriodo"].ToString())
            {

                //agregar todos los promedios de cada materia
                Periodos.AppendChild(PeriodoPar);
                foreach (DataRow m in dtm.Rows)
                {
                    string prom;
                    //obtengo el promedio del periodo
                    GetNotaPromedioPeriodo(PeriodoPar.GetAttribute("NroPeriodo"), alumno.GetAttribute("idSede"), alumno.GetAttribute("IdAlumnoCurso"), m["IdMateria"].ToString(), out prom);
                    addPromedioBoletin(PeriodoPar, prom, m["IdMateria"].ToString());
                    Periodos.AppendChild(PeriodoPar);
                }

                sPeriodoactual = r["nroPeriodo"].ToString();
                PeriodoPar = dom.CreateElement("Periodo");
            }

            Periodo.SetAttribute("Estilo", "TDQuincena");
            Periodo.SetAttribute("IdPeriodo", r["IdPeriodo"].ToString());
            Periodo.SetAttribute("FechaDesde", DateTime.Parse(r["FechaDesde"].ToString()).ToString("dd/MM/yyyy"));
            Periodo.SetAttribute("FechaHasta", DateTime.Parse(r["FechaHasta"].ToString()).ToString("dd/MM/yyyy"));
            Periodo.SetAttribute("Descripcion", r["Descripcion"].ToString());
            Periodo.SetAttribute("Particion", r["Particion"].ToString());

            //agrga las notas del periodo
            foreach (DataRow m in dtm.Rows)
            {
                getNotasPeriodo(Periodo, int.Parse(m["IdMateria"].ToString()), int.Parse(r["IdPeriodo"].ToString()), int.Parse(alumno.GetAttribute("IdAlumnoCurso")));
                Periodos.AppendChild(Periodo);
            }
            //agrego el promedio del periodo actual
            PeriodoPar.SetAttribute("IdPeriodo", r["IdPeriodo"].ToString());
            PeriodoPar.SetAttribute("Estilo", "TDTrimestre");
            PeriodoPar.SetAttribute("FechaDesde", r["Descripcion"].ToString());
            PeriodoPar.SetAttribute("FechaHasta", "");
            PeriodoPar.SetAttribute("Descripcion", r["Descripcion"].ToString());
            PeriodoPar.SetAttribute("Particion", r["Particion"].ToString());
            PeriodoPar.SetAttribute("NroPeriodo", r["NroPeriodo"].ToString());
        }

        //agregar todos los promedios de cada materia
        Periodos.AppendChild(PeriodoPar);
        foreach (DataRow m in dtm.Rows)
        {
            string prom;
            GetNotaPromedioPeriodo(PeriodoPar.GetAttribute("NroPeriodo"), alumno.GetAttribute("idSede"), alumno.GetAttribute("IdAlumnoCurso"), m["IdMateria"].ToString(), out prom);
            addPromedioBoletin(PeriodoPar, prom, m["IdMateria"].ToString());
            Periodos.AppendChild(PeriodoPar);
        }


        #region Notas Finales

        //calcular los promedios de las particiones
        XmlElement PerFinal = calcularPromediosFinal(Periodos, dtm, "Promedio Final", idTipoPlanilla, idAlumno, c);
   
        //notas de diciembre
        Periodos.AppendChild(calcularPromediosDiciembre(PerFinal, Periodos, dtm, "Diciembre", c, idAlumno));
   

        //Sobre el PerFinal hay que hacer los calculos correspondientes
        //primero tengo que saber si se lleva algo a marzo
        XmlElement xMarzo = calcularPromediosMarzo(PerFinal, dtm, "Marzo", c, idAlumno);

           
        //notas de marzo
        Periodos.AppendChild(xMarzo);

        //agregamos el periodo final
        Periodos.AppendChild(PerFinal);
        alumno.AppendChild(Periodos);
        #endregion


        XmlNodeList xMaterias = Periodos.SelectNodes("//alumno/Materias/Materia");

        foreach (XmlNode xMateria in xMaterias)
        {
            Schooll.Model.NotasFinales nf = Schooll.Model.NotasFinales.FindFirst(Expression.Sql("IdMateria=" + int.Parse(xMateria.Attributes["IdMateria"].Value) + " and  IdAlumno = " + idAlumno.ToString()));
            if (nf == null)
                nf = new Schooll.Model.NotasFinales();

            nf.IdAlumno = idAlumno;
            nf.LastUpdate = System.DateTime.Now;
            nf.Node = xMateria.InnerXml.ToString();
            nf.IdMateria = int.Parse(xMateria.Attributes["IdMateria"].Value);
            XmlNode xNota = xMateria.SelectSingleNode("//Resumen[@Nombre='Promedio Final']/materia[@IdMateria='" + nf.IdMateria.ToString() + "']/nota/modalidad");
            if (xNota == null)
            {
                nf.Final = 0;
            }
            else
            {
                nf.Final = Decimal.Parse(xNota.Attributes["nota"].Value);
            }
            XmlNodeList xNotas = Periodos.SelectNodes("//Resumen[@Nombre='Diciembre']/materia[@IdMateria='" + xMateria.Attributes["IdMateria"].Value + "']/nota[1]");
            if (xNotas != null)
            {
                nf.Diciembre = xNotas.Count;

            }
            xNotas = Periodos.SelectNodes("//Resumen[@Nombre='Marzo']/materia[@IdMateria='" + xMateria.Attributes["IdMateria"].Value + "']/nota/modalidad");
            if (xNotas != null)
            {
                nf.Marzo = xNotas.Count;

            }
            nf.SaveAndFlush();

        }



        if (sGuardarEn.Length > 0) dom.Save(sGuardarEn);
        return dom;

    }

    private XmlElement calcularPromediosFinal(XmlElement Periodos, DataTable dtm, string Nombre, Int16 IdTipoPLanilla, int idAlumno, CursoAprobacion c)
    {
        XmlElement PerTot = dom.CreateElement("Resumen");
        PerTot.SetAttribute("Estilo", "TDResumen");
        PerTot.SetAttribute("Nombre", Nombre);
        foreach (DataRow m in dtm.Rows)
        {
            XmlElement materia = dom.CreateElement("materia");
            for (int i = 0; i < dtm.Columns.Count; i++)
            {
                materia.SetAttribute(dtm.Columns[i].ColumnName.ToString(), m[i].ToString());
            }
            //agrego el promedio final para la materia en cuestion
            Schooll.Model.NotasDiciembreMarzo ndm = NotasDiciembreMarzo.GetNotaByIdalumnoMateria(idAlumno, int.Parse(materia.Attributes["IdMateria"].Value));

            AddPromedioFinalNota(materia, Periodos, IdTipoPLanilla, ndm,  c);


            PerTot.AppendChild(materia);
        }

        return PerTot;
    }

    private XmlElement calcularPromediosDiciembre(XmlElement PerFinal, XmlElement Periodos, DataTable dtm, string Nombre, Schooll.Model.CursoAprobacion c, int idalumno)
    {

        //pone las notas de diciembre
        XmlElement PerTot = dom.CreateElement("Resumen");
        PerTot.SetAttribute("Estilo", "TDResumen");
        PerTot.SetAttribute("Nombre", Nombre);
        foreach (DataRow m in dtm.Rows)
        {
            XmlElement materia = dom.CreateElement("materia");
            for (int i = 0; i < dtm.Columns.Count; i++)
            {
                materia.SetAttribute(dtm.Columns[i].ColumnName.ToString(), m[i].ToString());
            }

            //si tiene nota en diciembre la muestro directamente
            //busco si tiene nota
            NotasDiciembreMarzo ndm = NotasDiciembreMarzo.GetNotaByIdalumnoMateria(idalumno, int.Parse(materia.Attributes["IdMateria"].Value));
            if (ndm != null)
            {
                //tiene nota de diciembre entonces la muestro
                materia.AppendChild(CreateNotaPromedio(ndm.Diciembre.ToString(), "Nota Obtenida:" + ndm.Diciembre.ToString(), ndm.Diciembre.ToString()));
            }
            else
            {

                //agrego el promedio final para la materia en cuestion
                //andalizar si se lleva a diciembre o no
                //obtengo la nota final
                XmlNode xNota = (XmlElement)PerFinal.SelectSingleNode("//materia[@IdMateria='" + materia.Attributes["IdMateria"].Value + "']/nota/modalidad");
                if (xNota != null)
                {
                    double dNota = double.Parse(xNota.Attributes["nota"].Value);

                    // evaluar si esta aprobado
                    // para esto tengo que ver si la nota final es mayor o igual
                    // q la nota con la que aprueba


                    if (dNota >= c.Marzo)
                    {
                        if (dNota < c.ApruebaCon)
                        {

                            // materia.AppendChild(CreateNotaPromedio(dNota.ToString(), "Se Lleva a Diciembre", "Diciembre"));
                            // buscar que promedio se lleva
                            XmlNodeList Promedios = Periodos.SelectNodes("//Periodo[@Estilo='TDTrimestre']/materia[@IdMateria='" + materia.Attributes["IdMateria"].Value + "']");
                            foreach (XmlNode xProme in Promedios)
                            {
                                double dProm;
                                dProm = double.Parse(xProme.SelectSingleNode("nota/modalidad").Attributes["nota"].Value);
                                if (dProm < c.ApruebaCon && dProm > 0)
                                {
                                    string sNota = xProme.FirstChild.FirstChild.Attributes["nota"].Value;

                                    materia.AppendChild(CreateNotaPromedio(sNota, "Nota Obtenida: " + sNota, formatPeriodo(xProme.ParentNode.Attributes["Descripcion"].Value)));
                                }
                            }
                        }
                        else
                        {
                            // si el ultimo trimestre es menor que 6 se lo lleva a diciembre
                            XmlNodeList Promedios = Periodos.SelectNodes("//Periodo[@Estilo='TDTrimestre']/materia[@IdMateria='" + materia.Attributes["IdMateria"].Value + "']");
                            XmlNode xPromes = Promedios.Item(Promedios.Count - 1);
                            double dProm;

                            dProm = double.Parse(xPromes.SelectSingleNode("nota/modalidad").Attributes["nota"].Value);

                            if (dProm < c.ApruebaCon && dProm > 0)
                            {
                                foreach (XmlNode xProme in Promedios)
                                {
                                    dProm = double.Parse(xProme.SelectSingleNode("nota/modalidad").Attributes["nota"].Value);
                                    if (dProm < c.ApruebaCon && dProm > 0)
                                    {
                                        string sNota = xProme.FirstChild.FirstChild.Attributes["nota"].Value;

                                        materia.AppendChild(CreateNotaPromedio(sNota, "Nota Obtenida:" + sNota, formatPeriodo(xProme.ParentNode.Attributes["Descripcion"].Value)));
                                    }
                                }
                            }
                        }
                    }
                }
            }
            PerTot.AppendChild(materia);
        }

        return PerTot;
    }

    private string formatPeriodo(string svalue)
    {
        return svalue.Substring(0, 1) + " " + svalue.Substring(svalue.Length - 1, 1);
    }
 
    
    private XmlElement calcularPromediosMarzo(XmlElement PerFinal, DataTable dtm, string Nombre, Schooll.Model.CursoAprobacion c, int idalumno)
    {
        XmlElement PerTot = dom.CreateElement("Resumen");
        PerTot.SetAttribute("Estilo", "TDResumen");
        PerTot.SetAttribute("Nombre", Nombre);
        foreach (DataRow m in dtm.Rows)
        {
            XmlElement materia = dom.CreateElement("materia");
            for (int i = 0; i < dtm.Columns.Count; i++)
            {
                materia.SetAttribute(dtm.Columns[i].ColumnName.ToString(), m[i].ToString());
            }
            //agrego el promedio final para la materia en cuestion
            //analizar si se lleva a diciembre o no
            //obtengo la nota final


            //si tiene nota en diciembre la muestro directamente
            //busco si tiene nota
            NotasDiciembreMarzo ndm = NotasDiciembreMarzo.GetNotaByIdalumnoMateria(idalumno, int.Parse(materia.Attributes["IdMateria"].Value));
          
            //obtinene la nota final
            XmlNode xNota = (XmlElement)PerFinal.SelectSingleNode("//materia[@IdMateria='" + materia.Attributes["IdMateria"].Value + "']/nota/modalidad");

            if (ndm == null)
            {
                if (xNota != null)
                {
                    double dNota = double.Parse(xNota.Attributes["nota"].Value);
                    if (dNota < c.Marzo && dNota > 0)
                    {
                        materia.AppendChild(CreateNotaPromedio("1", "Se Lleva a Marzo", "Marzo"));
                    }
                }
            }
            else
            {
                if (ndm.Marzo > 0)
                {
                    if (ndm.Marzo < c.Marzo || ndm.Marzo==99)
                    {
                        
                        xNota.Attributes["nota"].Value = "-1";
                        if (ndm.Marzo == 99)
                        {
                            xNota.Attributes["nota"].Value = "0";
                            materia.AppendChild(CreateNotaPromedio("0", "Marzo:" + ndm.Marzo, "Ausente"));
                        }
                        else
                        {
                            materia.AppendChild(CreateNotaPromedio("1", "Marzo:" + ndm.Marzo, "Previa:" + ndm.Marzo));
                        }
                        
                    }
                    else
                    {
                        xNota.Attributes["nota"].Value = ndm.Marzo.ToString();
                        materia.AppendChild(CreateNotaPromedio(ndm.Marzo.ToString(), "Marzo", ndm.Marzo.ToString()));
                    }
                }
                else
                {
                    if (xNota != null)
                    {
                        double dNota = double.Parse(xNota.Attributes["nota"].Value);
                        if (ndm.Diciembre < c.Diciembre && dNota > 0)
                        {
                            xNota.Attributes["nota"].Value = "-1";
                            materia.AppendChild(CreateNotaPromedio("1", "Marzo", "Marzo"));
                        }
                    }
                   
                }
            }


            PerTot.AppendChild(materia);
        }

        return PerTot;
    }

    private XmlElement CreateNotaPromedio(string nota, string Observacion, string letra)
    {
        return this.CreateNota("Promedio", nota, Observacion, letra);
    }
    private XmlElement CreateNota(string Modalidad, string snota, string observacion, string letra)
    {
        XmlElement nota = null;
        nota = dom.CreateElement("nota");
        nota.SetAttribute("Modalidad", Modalidad);
        XmlElement notaMod = dom.CreateElement("modalidad");
        notaMod.SetAttribute("nota", snota);
        notaMod.SetAttribute("observacion", observacion);
        notaMod.SetAttribute("Letra", letra);
        //notaMod.SetAttribute("esp", r["Letra"].ToString());
        nota.AppendChild(notaMod);
        return nota;
    }

    private void AddPromedioFinalNota(XmlElement Materia, XmlElement Periodos, Int16 IdTipoPlanilla, NotasDiciembreMarzo ntm, CursoAprobacion c)
    {
        string sObservacion = "";
        //tengo que leer todas las notas del los trimestres y cuatrimestres
        XmlElement nota = null;
        nota = dom.CreateElement("nota");
        nota.SetAttribute("Modalidad", "Promedio");
        //Periodo[@Estilo='TDTrimestre']/materia[@IdMateria='100']/nota/modalidad/@nota
        XmlNodeList Promedios = Periodos.SelectNodes("//Periodo[@Estilo='TDTrimestre']/materia[@IdMateria='" + Materia.Attributes["IdMateria"].Value + "']/nota/modalidad");
        //calculamos el promedio 
        // sin tomar en cuenta los ceros
        double notaSuma = 0;
        int cantidad = 0;
        foreach (XmlNode xNod in Promedios)
        {
            if (double.Parse(xNod.Attributes["nota"].Value) > 0)
            {
                cantidad++;
                notaSuma += double.Parse(xNod.Attributes["nota"].Value);
            }
        }
        XmlElement notaMod = dom.CreateElement("modalidad");

        double NotaPromedio;

        if (cantidad > 0)
        {
            NotaPromedio = (notaSuma / cantidad);
        }
        else
        {
            NotaPromedio = 0;
        }
        string sNota;

        if (ntm != null)
        {
            if (ntm.Marzo > 0)
            {//si tiene nota en marzo no se promedia y se pone la nota que saco en marzo
                sObservacion = "\nNota antes de Marzo:" + Math.Round(NotaPromedio, 2);
                NotaPromedio = ntm.Marzo;
                if (ntm.Marzo < c.Marzo)
                {
                    NotaPromedio = 0;
                }

            }
            else
            {
                //si la nota de diciembre es distinta de cero se promedia

                if (ntm.Diciembre > 0)
                {
                    sObservacion = "\nPromedio antes Diciembre:" + Math.Round(NotaPromedio, 2) + "\nNota Diciembre:" + ntm.Diciembre.ToString();

                    NotaPromedio += ntm.Diciembre;
                    NotaPromedio = NotaPromedio / 2;
                    sObservacion += "\nPromedio Final:" + Math.Round(NotaPromedio, 2);
                }
            }
        }


        //si la planilla es de primaria
        //se redondea si no no 
        if (IdTipoPlanilla == 1)
        {
            sNota = FormatearDecimales(
                            Redondear(
                                float.Parse(NotaPromedio.ToString()),
                                int.Parse(IdTipoPlanilla.ToString())
                                ));
        }
        else
        {
            sNota = FormatearDecimales(Math.Round(NotaPromedio, 2).ToString());
        }
        notaMod.SetAttribute("nota", sNota);

        notaMod.SetAttribute("observacion", "Cantidad de notas " + cantidad + sObservacion);

        if (IdTipoPlanilla == 1)
        {
            //si la planilla es la 1 se muestran letras
            string ssql = "select Letra from dbo.TipoNotas where numero like '" + sNota + "%' and idioma = " + +SchoolsBI.Materia.Buscar("IdMateria =" + Materia.Attributes["IdMateria"].Value).IdIdioma;

            DataTable dtsa = SchoolsBI.TipoNotas.Tabla(ssql);

            if (dtsa.Rows.Count > 0)
                sNota = dtsa.Rows[0][0].ToString();

        }

        notaMod.SetAttribute("Letra", sNota);
        //notaMod.SetAttribute("esp", r["Letra"].ToString());
        nota.AppendChild(notaMod);
        Materia.AppendChild(nota);
    }
    private void AddExamenes(XmlElement Periodos, DataTable dtm, string sNombre)
    {
        foreach (DataRow m in dtm.Rows)
        {
            XmlElement PerTot = dom.CreateElement("Resumen");
            PerTot.SetAttribute("Estilo", "TDResumen");
            PerTot.SetAttribute("Nombre", sNombre);
            for (int i = 0; i < dtm.Columns.Count; i++)
            {
                PerTot.SetAttribute(dtm.Columns[i].ColumnName.ToString(), m[i].ToString());
            }
            Periodos.AppendChild(PerTot);
        }

    }


    private void getNotasPeriodo(XmlElement node, int idMateria, int idPeriodo, int idAlumCurso)
    {
        string sql = "GetNotasBoletinPorMateria " + idMateria + "," + @idAlumCurso + "," + @idPeriodo;

        DataTable dt = Alumnos.Tabla(sql);

        XmlElement materia = dom.CreateElement("materia");
        materia.SetAttribute("IdMateria", idMateria.ToString());

        foreach (DataRow r in dt.Rows)
        {
            XmlElement nota = null;
            nota = (XmlElement)materia.SelectSingleNode("nota[@Modalidad='" + r["Modalidad"].ToString() + "']");
            if (nota == null)
            {
                nota = dom.CreateElement("nota");
            }
            nota.SetAttribute("Modalidad", r["Modalidad"].ToString());
            XmlElement notaMod = dom.CreateElement("modalidad");
            notaMod.SetAttribute("nota", r["nota"].ToString());
            notaMod.SetAttribute("observacion", r["observacion"].ToString());
            notaMod.SetAttribute("Letra", FormatearDecimales(r["Letra"].ToString()));
            notaMod.SetAttribute("esp", r["Letra"].ToString());
            nota.AppendChild(notaMod);
            materia.AppendChild(nota);
        }
        node.AppendChild(materia);
    }

    private void addPromedioBoletin(XmlElement node, string Promedio, string idMateria)
    {
        XmlElement materia = dom.CreateElement("materia");
        materia.SetAttribute("IdMateria", idMateria.ToString());

        SchoolsBI.Materia oMat = SchoolsBI.Materia.Buscar("IdMateria = " + idMateria);


        string sSql = @"select Letra, idTipoPlanilla from tiponotas tn
                        inner join materia  on idioma = ididioma
                        where numero = " + Redondear(Single.Parse(Promedio), oMat.idTipoPlanilla) + " and idmateria = " + idMateria;

        DataTable dt = Alumnos.Tabla(sSql);


        XmlElement nota = dom.CreateElement("nota");
        nota.SetAttribute("Modalidad", "Promedio");
        XmlElement notaMod = dom.CreateElement("modalidad");
        notaMod.SetAttribute("nota", Redondear(Single.Parse(Promedio), oMat.idTipoPlanilla));
        if (dt.Rows.Count == 0)
        {
            notaMod.SetAttribute("Letra", Redondear(Single.Parse(Promedio), oMat.idTipoPlanilla));
            notaMod.SetAttribute("esp", Redondear(Single.Parse(Promedio), oMat.idTipoPlanilla));
        }
        else
        {
            if (dt.Rows[0]["idTipoPlanilla"].ToString() == "1")
            {
                notaMod.SetAttribute("Letra", dt.Rows[0]["letra"].ToString());
                notaMod.SetAttribute("esp", dt.Rows[0]["letra"].ToString());
            }
            else
            {
                notaMod.SetAttribute("Letra", Redondear(Single.Parse(Promedio), oMat.idTipoPlanilla));
                notaMod.SetAttribute("esp", Redondear(Single.Parse(Promedio), oMat.idTipoPlanilla));
            }
        }
        notaMod.SetAttribute("observacion", "");
        nota.AppendChild(notaMod);
        materia.AppendChild(nota);
        node.AppendChild(materia);
    }
    #endregion

    #region funciones

    private static string FormatearDecimales(string valor)
    {
        valor = valor.Replace(',', '.');
        if (valor.IndexOf(".") > 0)
        {
            valor = Convert.ToSingle(valor).ToString();
        }
        return valor;
    }
    #endregion


}
class PromedioConcepto
{
    private double _suma;
    private int _cantidad;
    public void add(double value)
    {
        _suma += value;
        _cantidad++;
    }
    public double promedio
    {
        get
        {
            if (_cantidad == 0)
            {
                return 0;
            }
            else
            {
                return _suma / _cantidad;
            }
        }
    }
}


